package com.haohan.cloud.scm.product.core.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.haohan.cloud.scm.api.constant.enums.product.SortingStatusEnum;
import com.haohan.cloud.scm.api.constant.enums.saleb.BuyOrderStatusEnum;
import com.haohan.cloud.scm.api.product.entity.*;
import com.haohan.cloud.scm.api.product.req.CreateSortingOrderReq;
import com.haohan.cloud.scm.api.product.trans.SortingOrderDetailTrans;
import com.haohan.cloud.scm.api.product.trans.SortingOrderTrans;
import com.haohan.cloud.scm.api.saleb.entity.BuyOrder;
import com.haohan.cloud.scm.api.saleb.entity.BuyOrderDetail;
import com.haohan.cloud.scm.api.saleb.req.BuyOrderReq;
import com.haohan.cloud.scm.api.saleb.req.UpdateBuyOrderStatusReq;
import com.haohan.cloud.scm.common.tools.exception.ErrorDataException;
import com.haohan.cloud.scm.product.core.IProductSortingOrderService;
import com.haohan.cloud.scm.product.service.ShipOrderDetailService;
import com.haohan.cloud.scm.product.service.ShipOrderService;
import com.haohan.cloud.scm.product.service.SortingOrderDetailService;
import com.haohan.cloud.scm.product.service.SortingOrderService;
import com.haohan.cloud.scm.product.utils.ScmProductUtils;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @author dy
 * @date 2019/7/5
 */
@Service
@AllArgsConstructor
public class ProductSortingOrderServiceImpl implements IProductSortingOrderService {

    private final SortingOrderService sortingOrderService;
    private final SortingOrderDetailService sortingOrderDetailService;
    private final ScmProductUtils scmProductUtils;
    private final ShipOrderService shipOrderService;
    private final ShipOrderDetailService shipOrderDetailService;

    /**
     * 新增货品分拣单  根据B客户订单
     *  已有时不新增
     * @param orderReq
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public SortingOrder createSortingOrder(CreateSortingOrderReq orderReq) {
        // 查 订单及明细
        BuyOrderReq req = new BuyOrderReq();
        req.setBuyId(orderReq.getBuyId());
        req.setPmId(orderReq.getPmId());
        BuyOrder order = scmProductUtils.queryOneByBuyOrderReq(req);
        // 查询 分拣单
        QueryWrapper<SortingOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(SortingOrder::getPmId, order.getPmId())
                .eq(SortingOrder::getBuyId, order.getBuyId());
        SortingOrder sortingOrder = sortingOrderService.getOne(queryWrapper,false);
        if(null != sortingOrder){
            return sortingOrder;
        }
        //创建分拣单
        sortingOrder = SortingOrderTrans.createSortingOrder(order);
        sortingOrderService.save(sortingOrder);
        String sortingSn = sortingOrder.getSortingOrderSn();

        List list = scmProductUtils.queryBuyOrderDetailList(order.getBuyId());
        for(Object obj : list){
            //创建分拣单明细
            BuyOrderDetail detail = BeanUtil.toBean(obj, BuyOrderDetail.class);
            // 初始化时无货品信息
            ProductInfo info = new ProductInfo();
            SortingOrderDetail sortingOrderDetail = SortingOrderDetailTrans.createSortingOrderDetailTrans(detail, info);
            sortingOrderDetail.setSortingOrderSn(sortingSn);
            sortingOrderDetailService.save(sortingOrderDetail);
        }
        return sortingOrder;
    }

    /**
     * 分拣单明细 开始分拣
     * @param sortingOrderDetail 必须SortingDetailSn/ pmId /SortingNumber
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean sortingDetailConfirm(SortingOrderDetail sortingOrderDetail) {
        String sortingDetailSn = sortingOrderDetail.getSortingDetailSn();
        // 状态需为 可分拣/已分拣
        QueryWrapper<SortingOrderDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(SortingOrderDetail::getPmId, sortingOrderDetail.getPmId())
                .eq(SortingOrderDetail::getSortingDetailSn, sortingDetailSn)
                .and(q -> q.eq(SortingOrderDetail::getSortingStatus, SortingStatusEnum.sorting)
                        .or()
                        .eq(SortingOrderDetail::getSortingStatus, SortingStatusEnum.selected)
                );
        SortingOrderDetail detail = sortingOrderDetailService.getOne(queryWrapper);
        if(null == detail){
            return false;
        }
        // 分拣单明细  修改分拣数量 修改状态:已分拣
        SortingOrderDetail update = new SortingOrderDetail();
        update.setId(detail.getId());
        update.setSortingNumber(sortingOrderDetail.getSortingNumber());
        update.setSortingStatus(SortingStatusEnum.selected);
        sortingOrderDetailService.updateById(update);
        // 确认 分拣单 为已分拣
        sortingOrderConfirm(detail.getSortingOrderSn());
        return true;
    }

    /**
     * 修改分拣单状态为 已分拣
     *
     * @param sortingOrderSn
     * @return
     */
    @Override
    public Boolean sortingOrderConfirm(String sortingOrderSn) {
        // 需分拣单状态 不为 已分拣
        QueryWrapper<SortingOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(SortingOrder::getSortingOrderSn, sortingOrderSn)
                .ne(SortingOrder::getSortingStatus, SortingStatusEnum.selected);
        SortingOrder sortingOrder = sortingOrderService.getOne(queryWrapper);
        if(null == sortingOrder){
            return false;
        }
        // 判断是否所有明细已分拣
        if(!checkDetailStatus(sortingOrderSn)){
            return false;
        }
        // 修改分拣单状态为已分拣
        SortingOrder update = new SortingOrder();
        update.setId(sortingOrder.getId());
        update.setSortingStatus(SortingStatusEnum.selected);
        sortingOrderService.updateById(update);
        return true;
    }

    /**
     * 判断是否所有明细已分拣
     * @param sortingOrderSn
     */
    private boolean checkDetailStatus(String sortingOrderSn) {
        QueryWrapper<SortingOrderDetail> queryWrapper = new QueryWrapper<>();
        // 未分拣的明细数量
        queryWrapper.lambda()
                .eq(SortingOrderDetail::getSortingOrderSn, sortingOrderSn)
                .and(q -> q.eq(SortingOrderDetail::getSortingStatus, SortingStatusEnum.wait)
                        .or()
                        .eq(SortingOrderDetail::getSortingStatus, SortingStatusEnum.sorting)
                );
        int num = sortingOrderDetailService.count(queryWrapper);
        return (num == 0);
    }

    /**
     * 分拣单 确认完成
     * @param order 实体对象 必需完整属性
     * @return  执行失败抛出异常
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void confirmSortingFinish(SortingOrder order){
        // 状态为 已分拣
        if(order.getSortingStatus() != SortingStatusEnum.selected){
            throw new ErrorDataException("分拣单状态有误");
        }
        // 修改 分拣单及明细 状态 已完成
        SortingOrder update = new SortingOrder();
        update.setId(order.getId());
        update.setSortingStatus(SortingStatusEnum.finish);
        QueryWrapper<SortingOrderDetail> query = new QueryWrapper<>();
        query.lambda()
                .eq(SortingOrderDetail::getSortingOrderSn, order.getSortingOrderSn());
        List<SortingOrderDetail> detailList = sortingOrderDetailService.list(query);
        if (CollUtil.isEmpty(detailList)){
            throw new ErrorDataException("分拣单无明细信息");
        }
        SortingOrderDetail updateDetail = new SortingOrderDetail();
        updateDetail.setSortingStatus(SortingStatusEnum.finish);
        // 创建配送明细
        List<ShipOrderDetail> shipDetailList = new ArrayList<>();
        ShipOrderDetail shipDetail;
        // B订单 明细
        List<BuyOrderDetail> buyOrderDetailList = new ArrayList<>();
        for(SortingOrderDetail detail: detailList){
            if(detail.getSortingStatus()!=SortingStatusEnum.selected || null == detail.getSortingNumber()){
                throw new ErrorDataException("分拣单明细有误");
            }
            updateDetail.setId(detail.getId());
            sortingOrderDetailService.updateById(updateDetail);
            shipDetail = SortingOrderDetailTrans.createShipDetail(detail);
            shipDetailList.add(shipDetail);
            // B订单 明细
            BuyOrderDetail updateBuyDetail = new BuyOrderDetail();
            updateBuyDetail.setBuyDetailSn(detail.getBuyDetailSn());
            updateBuyDetail.setStatus(BuyOrderStatusEnum.delivery);
            updateBuyDetail.setGoodsNum(detail.getSortingNumber());
            buyOrderDetailList.add(updateBuyDetail);
        }
        sortingOrderService.updateById(update);
        // 修改 B订单及明细  分拣数量 待发货
        UpdateBuyOrderStatusReq updateReq = new UpdateBuyOrderStatusReq();
        updateReq.setPmId(order.getPmId());
        updateReq.setBuyId(order.getBuyId());
        updateReq.setStatus(BuyOrderStatusEnum.delivery);
        updateReq.setDetailList(buyOrderDetailList);
        if(!scmProductUtils.updateBuyOrderStatus(updateReq)){
            throw new ErrorDataException("B订单更新失败");
        }
        // 创建 配送单
        ShipOrder shipOrder = SortingOrderTrans.createShipOrder(order);
        shipOrderService.save(shipOrder);
        String shipSn = shipOrder.getShipId();
        for(ShipOrderDetail detail : shipDetailList){
            detail.setShipId(shipSn);
            shipOrderDetailService.save(detail);
        }
    }


}
